home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Library / Manuels & Misc / Assembly / AOA.ZIP / CH19 / BARRIER.ASM < prev    next >
Encoding:
Assembly Source File  |  1994-07-21  |  7.2 KB  |  312 lines

  1. ; BARRIER.ASM
  2. ;
  3. ; This sample program demonstrates how to use the Standard Library's
  4. ; semaphore objects to synchronize several processes at a barrier.
  5. ; This program is similar to the MULTIDOS.ASM program insofar as the
  6. ; background processes all print a set of strings.  However, rather than
  7. ; using an inelegant delay loop to synchronize the foreground and background
  8. ; processes, this code uses barrier synchronization to achieve this.
  9.  
  10.         .xlist
  11.         include     stdlib.a
  12.         includelib    stdlib.lib
  13.         .list
  14.  
  15.  
  16. dseg        segment    para public 'data'
  17.  
  18. BarrierSemaph    semaphore    {0}        ;Must init SemaCnt to zero.
  19. DOSsmaph    semaphore    {}
  20.  
  21. ; Macros to wait and release the DOS semaphore:
  22.  
  23. DOSWait        macro
  24.         push    es
  25.         push    di
  26.         lesi    DOSsmaph
  27.         WaitSemaph
  28.         pop    di
  29.         pop    es
  30.         endm
  31.  
  32. DOSRls        macro
  33.         push    es
  34.         push    di
  35.         lesi    DOSsmaph
  36.         RlsSemaph
  37.         pop    di
  38.         pop    es
  39.         endm
  40.  
  41.  
  42. ; Macro to synchronize on a barrier:
  43.  
  44. Barrier        macro    Wait4Cnt
  45.         local    AllHere, AllDone
  46.         cmp    es:[di].semaphore.SemaCnt, -(Wait4Cnt-1)
  47.         jle    AllHere
  48.         WaitSemaph
  49.         cmp    es:[di].semaphore.SemaCnt, 0
  50.         jge    AllDone
  51. AllHere:    RlsSemaph
  52. AllDone:
  53.         endm
  54.  
  55.  
  56.  
  57.  
  58. ; PCBs for our background processes:
  59.  
  60. BkgndPCB2    pcb    {0,offset EndStk2, seg EndStk2}
  61. BkgndPCB3    pcb    {0,offset EndStk3, seg EndStk3}
  62.  
  63. ; Data the foreground and background processes print:
  64.  
  65. StrPtrs1    dword    str1_a, str1_b, str1_c, str1_d, str1_e, str1_f
  66.         dword    str1_g, str1_h, str1_i, str1_j, str1_k, str1_l
  67.         dword    0
  68.  
  69. str1_a        byte    "Foreground: string 'a'",cr,lf,0
  70. str1_b        byte    "Foreground: string 'b'",cr,lf,0
  71. str1_c        byte    "Foreground: string 'c'",cr,lf,0
  72. str1_d        byte    "Foreground: string 'd'",cr,lf,0
  73. str1_e        byte    "Foreground: string 'e'",cr,lf,0
  74. str1_f        byte    "Foreground: string 'f'",cr,lf,0
  75. str1_g        byte    "Foreground: string 'g'",cr,lf,0
  76. str1_h        byte    "Foreground: string 'h'",cr,lf,0
  77. str1_i        byte    "Foreground: string 'i'",cr,lf,0
  78. str1_j        byte    "Foreground: string 'j'",cr,lf,0
  79. str1_k        byte    "Foreground: string 'k'",cr,lf,0
  80. str1_l        byte    "Foreground: string 'l'",cr,lf,0
  81.  
  82. StrPtrs2    dword    str2_a, str2_b, str2_c, str2_d, str2_e, str2_f
  83.         dword    str2_g, str2_h, str2_i
  84.         dword    0
  85.  
  86. str2_a        byte    "Background 1: string 'a'",cr,lf,0
  87. str2_b        byte    "Background 1: string 'b'",cr,lf,0
  88. str2_c        byte    "Background 1: string 'c'",cr,lf,0
  89. str2_d        byte    "Background 1: string 'd'",cr,lf,0
  90. str2_e        byte    "Background 1: string 'e'",cr,lf,0
  91. str2_f        byte    "Background 1: string 'f'",cr,lf,0
  92. str2_g        byte    "Background 1: string 'g'",cr,lf,0
  93. str2_h        byte    "Background 1: string 'h'",cr,lf,0
  94. str2_i        byte    "Background 1: string 'i'",cr,lf,0
  95.  
  96. StrPtrs3    dword    str3_a, str3_b, str3_c, str3_d, str3_e, str3_f
  97.         dword    str3_g, str3_h, str3_i
  98.         dword    0
  99.  
  100. str3_a        byte    "Background 2: string 'j'",cr,lf,0
  101. str3_b        byte    "Background 2: string 'k'",cr,lf,0
  102. str3_c        byte    "Background 2: string 'l'",cr,lf,0
  103. str3_d        byte    "Background 2: string 'm'",cr,lf,0
  104. str3_e        byte    "Background 2: string 'n'",cr,lf,0
  105. str3_f        byte    "Background 2: string 'o'",cr,lf,0
  106. str3_g        byte    "Background 2: string 'p'",cr,lf,0
  107. str3_h        byte    "Background 2: string 'q'",cr,lf,0
  108. str3_i        byte    "Background 2: string 'r'",cr,lf,0
  109.  
  110. dseg        ends
  111.  
  112. cseg        segment    para public 'code'
  113.         assume    cs:cseg, ds:dseg
  114.  
  115. ; A replacement critical error handler.  This routine calls prcsquit
  116. ; if the user decides to abort the program.
  117.  
  118.  
  119. CritErrMsg    byte    cr,lf
  120.         byte    "DOS Critical Error!",cr,lf
  121.         byte    "A)bort, R)etry, I)gnore, F)ail? $"
  122.  
  123. MyInt24        proc    far
  124.         push    dx
  125.         push    ds
  126.         push    ax
  127.  
  128.         push    cs
  129.         pop    ds
  130. Int24Lp:    lea    dx, CritErrMsg
  131.         mov    ah, 9            ;DOS print string call.
  132.         int    21h
  133.  
  134.         mov    ah, 1            ;DOS read character call.
  135.         int    21h
  136.         and    al, 5Fh            ;Convert l.c. -> u.c.
  137.  
  138.         cmp    al, 'I'            ;Ignore?
  139.         jne    NotIgnore
  140.         pop    ax
  141.         mov    al, 0
  142.         jmp    Quit24
  143.  
  144. NotIgnore:    cmp    al, 'r'            ;Retry?
  145.         jne    NotRetry
  146.         pop    ax
  147.         mov    al, 1
  148.         jmp    Quit24
  149.  
  150. NotRetry:    cmp    al, 'A'            ;Abort?
  151.         jne    NotAbort
  152.         prcsquit            ;If quitting, fix INT 8.
  153.         pop    ax
  154.         mov    al, 2
  155.         jmp    Quit24
  156.  
  157. NotAbort:    cmp    al, 'F'
  158.         jne    BadChar
  159.         pop    ax
  160.         mov    al, 3
  161. Quit24:        pop    ds
  162.         pop    dx
  163.         iret
  164.  
  165. BadChar:    mov    ah, 2
  166.         mov    dl, 7            ;Bell character
  167.         jmp    Int24Lp
  168. MyInt24        endp
  169.  
  170.  
  171.  
  172. ; We will simply disable INT 23h (the break exception).
  173.  
  174. MyInt23        proc    far
  175.         iret
  176. MyInt23         endp
  177.  
  178.  
  179.  
  180. ; This background processes call DOS to print several strings to the
  181. ; screen.  In the meantime, the foreground process is also printing
  182. ; strings to the screen.  To prevent reentry, or at least a jumble of
  183. ; characters on the screen, this code uses semaphores to protect the
  184. ; DOS calls.  Therefore, each process will print one complete line
  185. ; then release the semaphore.  If the other process is waiting it will
  186. ; print its line.
  187.  
  188. BackGround1    proc
  189.         mov    ax, dseg
  190.         mov    ds, ax
  191.  
  192. ; Wait for everyone else to get ready:
  193.  
  194.         lesi    BarrierSemaph
  195.         barrier    3
  196.  
  197. ; Okay, start printing the strings:
  198.  
  199.         lea    bx, StrPtrs2        ;Array of str ptrs.
  200. PrintLoop:    cmp    word ptr [bx+2], 0    ;At end of pointers?
  201.         je    BkGndDone
  202.         les    di, [bx]        ;Get string to print.
  203.         DOSWait
  204.         puts                ;Calls DOS to print string.
  205.         DOSRls
  206.         add    bx, 4            ;Point at next str ptr.
  207.         jmp    PrintLoop
  208.  
  209. BkGndDone:    die
  210. BackGround1    endp
  211.  
  212.  
  213. BackGround2    proc
  214.         mov    ax, dseg
  215.         mov    ds, ax
  216.  
  217.         lesi    BarrierSemaph
  218.         barrier    3
  219.  
  220.         lea    bx, StrPtrs3        ;Array of str ptrs.
  221. PrintLoop:    cmp    word ptr [bx+2], 0    ;At end of pointers?
  222.         je    BkGndDone
  223.         les    di, [bx]        ;Get string to print.
  224.         DOSWait
  225.         puts                ;Calls DOS to print string.
  226.         DOSRls
  227.         add    bx, 4            ;Point at next str ptr.
  228.         jmp    PrintLoop
  229.  
  230. BkGndDone:    die
  231. BackGround2    endp
  232.  
  233.  
  234.  
  235. Main        proc
  236.         mov    ax, dseg
  237.         mov    ds, ax
  238.         mov    es, ax
  239.         meminit
  240.  
  241.  
  242. ; Initialize the INT 23h and INT 24h exception handler vectors.
  243.  
  244.         mov    ax, 0
  245.         mov    es, ax
  246.         mov    word ptr es:[24h*4], offset MyInt24
  247.         mov    es:[24h*4 + 2], cs
  248.         mov    word ptr es:[23h*4], offset MyInt23
  249.         mov    es:[23h*4 + 2], cs
  250.  
  251.         prcsinit        ;Start multitasking system.
  252.  
  253. ; Start the first background process:
  254.  
  255.         lesi    BkgndPCB2    ;Fire up a new process
  256.         fork
  257.         test    ax, ax        ;Parent's return?
  258.         je    StartBG2
  259.         jmp    BackGround1    ;Go do backgroun stuff.
  260.  
  261. ; Start the second background process:
  262.  
  263. StartBG2:    lesi    BkgndPCB3    ;Fire up a new process
  264.         fork
  265.         test    ax, ax        ;Parent's return?
  266.         je    ParentPrcs
  267.         jmp    BackGround2    ;Go do backgroun stuff.
  268.  
  269. ; The parent process will print a bunch of strings at the same time
  270. ; the background process is doing this.  We'll use the DOS semaphore
  271. ; to protect the call to DOS that PUTS makes.
  272.  
  273. ParentPrcs:     lesi    BarrierSemaph
  274.         barrier    3
  275.  
  276.         lea    bx, StrPtrs1        ;Array of str ptrs.
  277. PrintLoop:    cmp    word ptr [bx+2], 0    ;At end of pointers?
  278.         je    ForeGndDone
  279.         les    di, [bx]        ;Get string to print.
  280.         DOSWait
  281.         puts                ;Calls DOS to print string.
  282.         DOSRls
  283.         add    bx, 4            ;Point at next str ptr.
  284.         jmp    PrintLoop
  285.  
  286. ForeGndDone:    prcsquit
  287.  
  288. Quit:        ExitPgm                ;DOS macro to quit program.
  289. Main        endp
  290.  
  291. cseg            ends
  292.  
  293. sseg        segment    para stack 'stack'
  294.  
  295. ; Here are the stacks for the background processes we start
  296.  
  297. stk2        byte    1024 dup (?)
  298. EndStk2        word    ?
  299.  
  300. stk3        byte    1024 dup (?)
  301. EndStk3        word    ?
  302.  
  303. ;Here's the stack for the main program/foreground process.
  304.  
  305. stk        byte    1024 dup (?)
  306. sseg        ends
  307.  
  308. zzzzzzseg    segment    para public 'zzzzzz'
  309. LastBytes    db    16 dup (?)
  310. zzzzzzseg    ends
  311.         end    Main
  312.